package encrypt

import (
	"crypto/rand"
	"golang.org/x/crypto/salsa20"
)

type encryptSalsa20 struct {
	key [32]byte
}

func NewEncryptSalsa20(key string) Encrypter {
	e := new(encryptSalsa20)
	k := []byte(key)
	for i := 0; i < 32; i++ {
		if i == len(k) {
			break
		}
		e.key[i] = k[i]
	}
	return e
}

func autoBuf(buf []byte, l int) (out []byte) {
	if len(out) < l {
		out = make([]byte, l)
	} else {
		out = buf[:l]
	}
	return
}

func (e *encryptSalsa20) encrypt(buf []byte, in []byte, salt []byte) (out []byte, err error) {
	out = autoBuf(buf, len(in))
	salsa20.XORKeyStream(out, in, salt, &e.key)
	return
}

func (e *encryptSalsa20) decrypt(buf []byte, in []byte, salt []byte) (out []byte, err error) {
	out = autoBuf(buf, len(in))
	salsa20.XORKeyStream(out, in, salt, &e.key)
	return
}

func (e *encryptSalsa20) salt() (salt []byte) {
	salt = make([]byte, 8)
	_, err := rand.Read(salt)
	if err != nil {
		panic(err)
	}
	return
}

func (e *encryptSalsa20) cipher() int {
	return 1
}

func (e encryptSalsa20) String() string {
	return "salsa20"
}
